package com.abel.bigwater.dataserver.model.qdies

import com.abel.bigwater.data.BcdString
import com.abel.bigwater.dataserver.model.PacketCmdException
import com.abel.bigwater.dataserver.model.PacketDataLenException
import io.netty.buffer.ByteBuf

class DtenAsk485NowData(_len: Int) : DtenAskNowData(_len) {

    var proto = ProtoType.Meter485_188

    var status: Int? = null

    override var type = FuncType.Ask485Now

    override fun fill(buf: ByteBuf) {
        buf.apply {
            writeByte(if (good) 0xAA else 0xCC)

            writeBytes(sampleTimeBcd!!.hexArray)

            writeByte(internalAddr!!.toInt())
            writeByte(proto.code)
            writeFloat(reading!!)

            if (proto == ProtoType.Meter485_188) {
                writeShort(status!!)
            }
        }
    }

    override fun parse(buf: ByteBuf): Boolean {
        if (buf.readableBytes() < MIN_LEN) {
            throw PacketDataLenException("not enough bytes: ${buf.readableBytes()}")
        }

        buf.apply {
            val g1v = readUnsignedByte()
            good = g1v.toInt() == 0xAA

            sampleTimeBcd = BcdString.create(this, 5)
            internalAddr = readByte()
            val p1v = readByte()
            val p1 = ProtoType.values().find { it.code == p1v.toInt() }
                    ?: throw PacketCmdException("invalid protocol: $p1v")
            proto = p1

            reading = readFloat()

            if (proto == ProtoType.Meter485_188) {
                assert(readableBytes() >= 2)
                status = readUnsignedShort()
            }
        }
        return true
    }

    override fun count(): Int {
        return if (proto == ProtoType.Meter485_188) MIN_LEN + 2 else MIN_LEN
    }

    companion object {
        const val MIN_LEN = 1 + 5 + 1 + 1 + 4
    }
}